# Copyright (c) 2024, cy080585@126.com and contributors
# For license information, please see license.txt

from frappe import _,bold
import frappe
from frappe.model.document import Document
from frappe.utils import (
	add_days,
	cint,
	cstr,
	flt,
	get_link_to_form,
	now,
	nowtime,
	parse_json,
	today,
	get_time,
	now_datetime,
)

class PackingList(Document):

    def validate(self):
        self.validate_calculate_weight()
        self.validate_posting_time()

    def validate_calculate_weight(self):
        net_weight = 0.0
        total_qty=0.0
        total_amount=0.0
        for item in self.items:
            net_weight += flt(item.net_weight)
            total_qty += flt(item.qty)
            total_amount += flt(item.amount)

        self.net_weight_pkg=net_weight
        self.total_qty=total_qty
        self.total_amount=total_amount

    def validate_posting_time(self):
        now = now_datetime()
        self.posting_date = now.strftime("%Y-%m-%d")
        self.posting_time = now.strftime("%H:%M:%S.%f")


    def set_packing_and_voucher_values(self, parent, row):
        values_to_set = {}
        if not self.voucher_no or self.voucher_no != row.parent:
            values_to_set["voucher_no"] = row.parent

        if self.voucher_type != parent.doctype:
            values_to_set["voucher_type"] = parent.doctype

        if not self.voucher_detail_no or self.voucher_detail_no != row.name:
            values_to_set["voucher_detail_no"] = row.name

        if parent.get("posting_date") and (not self.posting_date or self.posting_date != parent.posting_date):
            values_to_set["posting_date"] = parent.posting_date or today()

        if parent.get("posting_time") and (not self.posting_time or self.posting_time != parent.posting_time):
            values_to_set["posting_time"] = parent.posting_time

        if values_to_set:
            self.db_set(values_to_set)

    # def on_trash(self):
    # 	# self.db_set({'voucher_no':None,'voucher_type':None})
    # 	self.flags.ignore_links = True
    # 	frappe.db.set_value(self.doctype,self.name,"voucher_no",None)
    # 	print("self.flags.ignore_links")
    # 	print(self.flags.ignore_links)
    # 	print('on_trash my  ok  '+self.voucher_no)

    # def before_cancel(self):
    # 	self.ignore_linked_doctypes = (
    # 		"Packing List",
    # 		"Packing Order Item",
    # 		"Packing Order"
    # 	)
        # sles=frappe.get_all('Packing Order Item',filters={"packing_list_items": self.name})
        # for sle in sles:
        # 	frappe.db.set_value("Packing Order Item", sle.name, "packing_list_items", None)
	
    def before_update_after_submit(self):
        amount_changed=self.has_value_changed("items")
        if amount_changed:
            self.validate_calculate_weight()



@frappe.whitelist()
def add_packing_items_ledgers(entries, child_row, doc, do_not_save=False) -> object:


	# print(type(child_row))
	if isinstance(child_row, str):
		child_row = frappe._dict(parse_json(child_row))

	if isinstance(entries, str):
		entries = parse_json(entries)

	parent_doc = doc
	if parent_doc and isinstance(parent_doc, str):
		parent_doc = parse_json(parent_doc)
	
	# print(type(child_row))

	if frappe.db.exists("Packing List", child_row.packing_list_items):
		sb_doc = update_packing_items_ledgers(entries, child_row, parent_doc)
	else:
		sb_doc = create_packing_items_ledgers(
			entries, child_row, parent_doc, do_not_save=do_not_save
		)

	return sb_doc


def update_packing_items_ledgers(entries, child_row, parent_doc) -> object:
	if parent_doc.docstatus == 0:
		doc = frappe.get_doc("Packing List", child_row.packing_list_items)
		doc.voucher_detail_no = child_row.name
		doc.posting_date = parent_doc.posting_date
		doc.currency=parent_doc.currency
		doc.customer=parent_doc.customer
		doc.customer_name=parent_doc.customer_name
		doc.set("items", [])

		for d in entries:
			doc.append(
				"items",
				{
					"item_code": d.get("item_code"),
					"item_name": d.get("item_name"),
					"stock_uom": d.get("stock_uom") or "",
					"rate": flt(d.get("rate")) or 0.0,
					"net_weight": flt(d.get("net_weight")) or 0.0,
					"amount": flt(d.get("qty"))*flt(d.get("rate")),
					"qty": flt(d.get("qty")) or 0.0,
					"size": d.get("size") or "",
					"customs_item_code": d.get("customs_item_code") or "",
					"order_name":d.get("order_name") or '',
					"order_item_name":d.get("order_item_name") or '',
				},
			)

		doc.save(ignore_permissions=True)
	else:
		now = now_datetime()
		posting_date = now.strftime("%Y-%m-%d")
		posting_time = now.strftime("%H:%M:%S.%f")
		total_qty=0.0
		total_amount=0.0
		total_weight = 0.0
		# for row in doc.items:
		# 	for d in entries:
		# 		if row.name==d.get("row_id"):
		# 			row.db_set({
		# 				"rate": flt(d.get("rate")),
		# 				"amount": flt(d.get("qty")) * flt(d.get("rate")),
		# 				"net_weight": flt(d.get("net_weight")) or 0.0,
		# 			})
		# 			total_weight+=flt(d.get("net_weight")) or 0.0
		for d in entries:
			frappe.db.set_value("Packing List Item", d.get('row_id'),{
				"rate": flt(d.get("rate")),
				"amount": flt(d.get("qty")) * flt(d.get("rate")),
				"net_weight": flt(d.get("net_weight",0.0)) ,
				"item_name":d.get("item_name"),
				"customs_item_code":d.get("customs_item_code") or ""
			})
			total_weight+=flt(d.get("net_weight",0.0))
			total_qty+=flt(d.get("qty",0.0))
			total_amount+=flt(d.get("qty",0.0)) * flt(d.get("rate",0.0))
		
		frappe.db.set_value("Packing List", child_row.packing_list_items,{
			"net_weight_pkg":total_weight,"posting_date": posting_date,"posting_time": posting_time,"total_qty":total_qty,"total_amount":total_amount})

		doc = frappe.get_doc("Packing List", child_row.packing_list_items)
		# print(doc)

		# doc.db_set({"net_weight_pkg":total_weight,"posting_date": posting_date,"posting_time": posting_time})

	frappe.msgprint(frappe._("Packing List Items updated"), alert=True)

	return doc



def create_packing_items_ledgers(
	entries, child_row, parent_doc, do_not_save=False
) -> object:

	doc = frappe.get_doc(
		{
			"doctype": "Packing List",
			"voucher_type": child_row.parenttype,
			"posting_date": parent_doc.get("posting_date"),
			"company": parent_doc.get("company"),
			"Currency":parent_doc.get("currency"),
			"customer": parent_doc.get("customer"),
			"customer_name": parent_doc.get("customer_name"),
		}
	)

	for row in entries:
		d = frappe._dict(row)
		doc.append(
			"items",
			{
				"item_code": d.get("item_code"),
				"item_name": d.get("item_name"),
				"stock_uom": d.get("stock_uom") or "",
				"rate": flt(d.get("rate")) or 0.0,
				"net_weight": flt(d.get("net_weight")) or 0.0,
				"amount": flt(d.get("qty"))*flt(d.get("rate")),
				"qty": flt(d.get("qty")) or 0.0,
				"size": d.get("size") or "",
				"customs_item_code": d.get("customs_item_code") or "",
				"order_name":d.get("order_name") or '',
				"order_item_name":d.get("order_item_name") or '',
			},
		)

	doc.save()

	if do_not_save:
		frappe.db.set_value(child_row.doctype, child_row.name, "packing_list_items", doc.name)

	frappe.msgprint(_("Packing List Items created"), alert=True)

	return doc


@frappe.whitelist()
def get_packing_items_ledgers(name):
	if name:
		res = frappe.get_all('Packing List Item', filters={'parent': name}, fields=["name as row_id",'item_code','item_name','stock_uom','rate','net_weight','qty','amount','size','customs_item_code','name as order_item_name','parent as order_name'],order_by='idx')
		return res